#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <semaphore.h>

/*次线程的个数*/
#define SECON_PTH_NUMS 	2

/*线程信号量集合中信号量的个数*/
#define SEM_NUMS 		1

/*线程的参数结构体*/
typedef struct pthread_arg{
	int fd;			/*线程操作的文件描述符*/
	int pthno;		/*自定义的线程编号*/
	pthread_t tid;	/*线程ID*/
}ptharg;


/*全局变量结构体*/
struct global_var{
	ptharg pthargs[SECON_PTH_NUMS];			/*线程参数*/
	sem_t sem[SEM_NUMS];					/* 初始化线程信号量集合 */
}glbva;


/*报错函数*/
void print_err(char *str, int line, int err_no)
{
	printf("%d,%s:%s",line,str,strerror(err_no));
	exit(-1);
}


/*线程函数*/
void * pth_fun(void *pth_arg)
{
	int fd = ((ptharg *)(pth_arg))->fd;
	pthread_t tid = ((ptharg *)pth_arg)->tid;
	int pthno = ((ptharg *)pth_arg)->pthno;

	printf("pthno=%d , tid =%lu\n",pthno,tid);

	printf("pthno=%d , tid2 =%lu\n",pthno,pthread_self());


	while(1)
	{
		sem_wait(&glbva.sem[0]);	/*线程信号量p操作，信号量值减1*/
		write(fd,"hello ",6);
		write(fd,"world\n",6);
		sem_post(&glbva.sem[0]);	/*线程信号量v操作，信号量值加1*/

	}
	return NULL;	
} 



void signal_fun(int signo)
{
	int i = 0;
	int ret = 0;

	/* 删除信号量集合 */
	for(i=0;i<SEM_NUMS;i++)
	{
		ret = sem_destroy(&glbva.sem[i]);
		if(ret !=0) print_err("sem_destroy fail",__LINE__,errno);
	}

	exit(0);/*退出整个进程*/
}


int main(void)
{
	int ret = 0;
	int i = 0;
	int fd =0;
	
	/*初始化信号量集合*/
	for(i=0;i<SEM_NUMS;i++)
	{
		if(i==0) ret = sem_init(&glbva.sem[i],0,1);
		else ret = sem_init(&glbva.sem[i],0,0);

		if(ret !=0) print_err("sem_init fail",__LINE__,errno);
	}


	signal(SIGINT,signal_fun);


	fd = open("./file",O_RDWR|O_CREAT|O_TRUNC,0664);
	if(fd == -1) print_err("open ",__LINE__,errno);
	

	for(i=0;i<SECON_PTH_NUMS;i++)
	{
		glbva.pthargs[i].fd = fd;
		glbva.pthargs[i].pthno = i;
													
		ret = pthread_create(&glbva.pthargs[i].tid,NULL,pth_fun,&glbva.pthargs[i]);
		if(ret != 0) print_err("pthread_create",__LINE__,ret);

		//pthread_detach(glbva.pthargs[i].tid);
	}
	

	while(1)
	{
		sem_wait(&glbva.sem[0]); /*线程信号量p操作，信号量值减1*/
		write(fd,"hello ",6);
		write(fd,"world\n",6);
		sem_post(&glbva.sem[0]);/*线程信号量v操作，信号量值加1*/
	}
	
	return 0;
}






































